﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TireService.Data;
using System.Web.Security;
using System.Collections;
using System.Configuration;

namespace TireService.Web.View.ServiceView
{
    public partial class EditCompletion : System.Web.UI.Page
    {
        #region Public Properties

        public int ServiceCarScheduleDetailId
        {
            get
            {
                if (ViewState["_servicecarscheduledetailid"] != null)
                    return (int)ViewState["_servicecarscheduledetailid"];
                else
                    return 0;
            }
            set
            {
                ViewState["_servicecarscheduledetailid"] = value;
            }
        }

        public List<int> MarkedServiceDetails
        {
            get
            {
                if (ViewState["_markedservicedetails"] != null)
                    return (List<int>)ViewState["_markedservicedetails"];
                else
                    return null;
            }
            set
            {
                ViewState["_markedservicedetails"] = value;
            }
        }

        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Page.IsPostBack != true)
            {
                TireServiceDB db = new TireServiceDB();

                // Bind data to dropdown lists
                ddlFromTireSpeedIndex.DataSource = db.GetTireSpeedIndex();
                ddlFromTireSpeedIndex.ValueField = "TireSpeedIndexId";
                ddlFromTireSpeedIndex.TextField = "Description";
                ddlFromTireSpeedIndex.DataBind();

                ddlFromTireLoadIndex.DataSource = db.GetTireLoadIndex();
                ddlFromTireLoadIndex.ValueField = "TireLoadIndexId";
                ddlFromTireLoadIndex.TextField = "Description";
                ddlFromTireLoadIndex.DataBind();

                ddlFromTireBrand.DataSource = db.GetTireBrands();
                ddlFromTireBrand.ValueField = "TireBrandId";
                ddlFromTireBrand.TextField = "Description";
                ddlFromTireBrand.DataBind();

                db.Dispose();

                // Get multiedit id's
                if (Session["MarkedServiceDetails"] != null)
                {
                    this.MarkedServiceDetails = (List<int>)Session["MarkedServiceDetails"];
                    this.ServiceCarScheduleDetailId = Convert.ToInt32(MarkedServiceDetails.First());
                }

                // Get ServiceCarScheduleDetailId
                try
                {
                    // Get Id and save to propertie
                    if (Session["ServiceCarScheduleDetailId"] != null) this.ServiceCarScheduleDetailId = Convert.ToInt32(Session["ServiceCarScheduleDetailId"]);
                    if (Request.QueryString["ServiceCarScheduleDetailId"] != null)
                    {
                        this.ServiceCarScheduleDetailId = Convert.ToInt32(Request.QueryString["ServiceCarScheduleDetailId"]);
                    }
                }
                catch (Exception)
                {
                    // Reset id
                    this.ServiceCarScheduleDetailId = 0;

                    // Nothing - invalid id, not an integer. Redirect to task completion page 
                    RedirectToTaskCompletionList();
                }

                bool MultiEdit = (this.MarkedServiceDetails != null);
                LoadServiceCarScheduleDetail(this.ServiceCarScheduleDetailId, MultiEdit);
            }
            
            if (this.ServiceCarScheduleDetailId == 0)
            {
                // Redirect to task completion page 
                RedirectToTaskCompletionList();
            }
        }

        protected void RedirectToTaskCompletionList()
        {
            Response.Redirect("~/View/ServiceView/Completion.aspx");
        }

        /// <summary>
        /// Function that load ServiceCarScheduleDetail and change UI
        /// </summary>
        /// <param name="LoadServiceCarScheduleDetailId">Id for ServiceCarScheduleDetail to load</param>
        /// <param name="MultiEdit">True/false value to change UI for multiedit or not</param>
        protected void LoadServiceCarScheduleDetail(int ServiceCarScheduleDetailId, bool MultiEdit)
        {
            // Set page propertie
            this.ServiceCarScheduleDetailId = ServiceCarScheduleDetailId;

            TireServiceDB db = new TireServiceDB();

            if (ServiceCarScheduleDetailId != 0)
            {
                ServiceCarScheduleDetailView detail = db.ServiceCarScheduleDetailViews.SingleOrDefault(p => p.ServiceCarScheduleDetailId == ServiceCarScheduleDetailId);
                //ServiceCarScheduleDetail detail = db.GetServiceCarScheduleDetail(ServiceCarScheduleDetailId);
                
                if (detail != null)
                {
                    // Bind item data to editform
                    TireSet tireset = db.GetTireSet(Convert.ToInt32(detail.FromTireSetId));

                    // Show container cargonumber
                    lblContainerCargoNumberValue.Text = detail.CargoRoomNumber.ToString() + "-" + detail.ContainerNumber;

                    // Set form fields
                    lblFromTireTypeValue.Text = db.GetTireTypeDescription(tireset.TireTypeId);
                    if (tireset.DummyTireSet)
                    {
                        // Is a dummy tireset - no values created yet, clear form   
                        ddlFromHeight.Value = "";
                        ddlFromSize.Value = "";
                        ddlFromWidth.Value = "";
                        ddlFromTireLoadIndex.Value = "";
                        ddlFromTireSpeedIndex.Value = "";
                        ddlFromTireBrand.Value = "";
                        txtFromTireBrandNote.Text = "";
                        txtFromManufactureDate.Value = "";
                        if (tireset.HubCaps) 
                        {
                            cbFromHubCaps.Checked = tireset.HubCaps;
                        }
                        else
                        {
                            cbFromHubCaps.Checked = false;
                        }
                        if (tireset.LockingBolt)
                        {
                            cbFromLockingBolt.Checked = tireset.LockingBolt;
                        }
                        else
                        {
                            cbFromLockingBolt.Checked = false;
                        }
                        if (tireset.RimProtection)
                        {
                            cbFromRimProtection.Checked = tireset.RimProtection;
                        }
                        else
                        {
                            cbFromRimProtection.Checked = false;
                        }
                        if (tireset.RunFlatTire)
                        {
                            cbFromRunFlatTire.Checked = tireset.RunFlatTire;
                        }
                        else
                        {
                            cbFromRunFlatTire.Checked = false;
                        }
                        ddlFromSocketWrenchSize.Value = "";
                    }
                    else
                    {
                        ddlFromHeight.Value = tireset.Height;
                        ddlFromSize.Value = tireset.Size;
                        ddlFromWidth.Value = tireset.Width;
                        ddlFromTireLoadIndex.Value = tireset.TireLoadIndexId;
                        ddlFromTireSpeedIndex.Value = tireset.TireSpeedIndexId;
                        ddlFromTireBrand.Value = tireset.TireBrandId;
                        txtFromTireBrandNote.Text = tireset.TireBrandNote;
                        txtFromManufactureDate.Value = Convert.ToDateTime(tireset.ManufactureDate);
                        cbFromHubCaps.Checked = tireset.HubCaps;
                        cbFromLockingBolt.Checked = tireset.LockingBolt;
                        cbFromRimProtection.Checked = tireset.RimProtection;
                        cbFromRunFlatTire.Checked = tireset.RunFlatTire;
                        ddlFromSocketWrenchSize.Value = tireset.SocketWrenchSize;
                    }
                }
                else
                {
                    // Detail NOT found - redirect to taskcompletion list
                    RedirectToTaskCompletionList();
                }
            }
            else
            {
                // No customer loaded - redirect to taskcompletion list
                RedirectToTaskCompletionList();
            }

            // Change UI based on multiedit input
            ChangeMultiEdit(MultiEdit, this.ServiceCarScheduleDetailId);

            // Dispose connection to database
            db.Dispose();
        }

        /// <summary>
        /// Function that change UI based on multiediting on/off
        /// </summary>
        /// <param name="MultiEdit">True/false value indicating if multiedit is on/off</param>
        /// <param name="ServiceCarScheduleDetailId">Id for ServiceCarScheduleDetail being edited</param>
        protected void ChangeMultiEdit(bool MultiEdit, int ServiceCarScheduleDetailId)
        {
            // Change UI for multiedit
            if (MultiEdit)
            {
                // Show index number and total numbers to edit
                lblMultiEdit.Text = "&nbsp;|&nbsp;Rediger flere udkørsler: " + (this.MarkedServiceDetails.IndexOf(ServiceCarScheduleDetailId) + 1).ToString() + " af " + this.MarkedServiceDetails.Count.ToString();

                // Change buttons
                btnSaveCustomerClose.Text = "Gem og afslut";
                btnSaveCustomer.Text = "Gem og gå til næste";
                lbtnNextCustomer.Enabled = (ServiceCarScheduleDetailId != (int)this.MarkedServiceDetails.Last());
                lbtnPreviousCustomer.Enabled = (ServiceCarScheduleDetailId != (int)this.MarkedServiceDetails.First());
            }
            else
            {
                btnSaveCustomer.Text = "Gem";
                lbtnNextCustomer.Visible = false;
                lbtnPreviousCustomer.Visible = false;
            }

            lbtnNextCustomer.Visible = MultiEdit;
            lbtnPreviousCustomer.Visible = MultiEdit;
            btnSaveCustomerClose.Visible = MultiEdit;
            lblMultiEdit.Visible = MultiEdit;
        }

        private void SaveTaskCompletion(int ServiceCarScheduleDetailId)
        {
            // Get tire pattern
            decimal LeftFrontTirePattern = Convert.ToDecimal(txtLF.Value);
            decimal LeftRearTirePattern = Convert.ToDecimal(txtLR.Value);
            decimal RightFrontTirePattern = Convert.ToDecimal(txtRF.Value);
            decimal RightRearTirePattern = Convert.ToDecimal(txtRR.Value);

            if (LeftFrontTirePattern <= 0 | LeftRearTirePattern <= 0 | RightFrontTirePattern <= 0 | RightRearTirePattern <= 0)
            {
                throw new ArgumentException("Dækmønstre er ikke angivet korrekt");
            }

            // Instantiate database connection
            TireServiceDB db = new TireServiceDB();

            // Fetch servicescheduledetail
            ServiceCarScheduleDetail detail = db.GetServiceCarScheduleDetail(ServiceCarScheduleDetailId);

            // Mark detail as completed
            detail.WorkCompleted = true;

            // Update car
            Car car = db.GetCar(Convert.ToInt32(detail.CarId));

            car.LastTireSetChangeDate = detail.ScheduleDate;
            car.NextTireSetChangePlanningDate = detail.ScheduleDate.AddMonths(4);
            car.CarStatusId = (int)Shared.CarStatus.TireChanged;

            // Fetch subscription (to see if balancing is included in customer subscription)
            CustomerSubscription subscription = db.GetCustomerSubscription(Convert.ToInt32(car.CustomerSubscriptionId));

            string subscriptionnumber = car.CustomerId.ToString() + "-" + subscription.SubscriptionId.ToString() + "-" + car.CustomerSubscriptionId.ToString();

            // Update tiresets 
            // Update from tireset
            TireSet FromTireset = db.GetTireSet(Convert.ToInt32(detail.FromTireSetId));
            TireSet ToTireset = db.GetTireSet(Convert.ToInt32(detail.ToTireSetId));

            // Create tiresetlog for fromtireset
            TireSetLogBLL bll = new TireSetLogBLL();
            bll.CreateTireSetLog(db, FromTireset, DateTime.Now, FromTireset.TireSetStatusId, (int)Shared.TireSetStatus.OnStock, new Guid(Membership.GetUser().ProviderUserKey.ToString()), "Hjul afmonteret og lagt på lager", LeftFrontTirePattern, RightFrontTirePattern, LeftRearTirePattern, RightRearTirePattern, ToTireset.ContainerCargoRoomId);

            // Create tiresetlog for totireset
            bll.CreateTireSetLog(db, ToTireset, DateTime.Now, ToTireset.TireSetStatusId, (int)Shared.TireSetStatus.MountedOnCar, new Guid(Membership.GetUser().ProviderUserKey.ToString()), "Hjul påmonteret kundens bil", null, null, null, null, null);

            // Placeholder properties for tiresetstatus and containercargoroomid
            int containercargoroomid = Convert.ToInt32(ToTireset.ContainerCargoRoomId);

            // Update totireset according to log
            ToTireset.TireSetStatusId = (int)Shared.TireSetStatus.MountedOnCar;
            ToTireset.ContainerCargoRoomId = null;

            // Update fromtireset according to log
            FromTireset.ContainerCargoRoomId = containercargoroomid;
            FromTireset.TireSetStatusId = (int)Shared.TireSetStatus.OnStock;
            FromTireset.Size = Convert.ToDecimal(ddlFromSize.Value);
            FromTireset.Height = Convert.ToDecimal(ddlFromHeight.Value);
            FromTireset.Width = Convert.ToDecimal(ddlFromWidth.Value);
            FromTireset.TireSpeedIndexId = Convert.ToInt32(ddlFromTireSpeedIndex.Value);
            FromTireset.TireLoadIndexId = Convert.ToInt32(ddlFromTireLoadIndex.Value);
            FromTireset.TireBrandId = Convert.ToInt32(ddlFromTireBrand.Value);
            FromTireset.TireBrandNote = txtFromTireBrandNote.Text;
            FromTireset.LockingBolt = cbFromLockingBolt.Checked;
            FromTireset.HubCaps = cbFromHubCaps.Checked;
            FromTireset.RunFlatTire = cbFromRunFlatTire.Checked;
            FromTireset.RimProtection = cbFromRimProtection.Checked;
            FromTireset.ExtraBolts = cbFromExtraBolts.Checked;
            FromTireset.ManufactureDate = Convert.ToDateTime(txtFromManufactureDate.Value);
            FromTireset.SocketWrenchSize = Convert.ToInt32(ddlFromSocketWrenchSize.Value);
            FromTireset.DummyTireSet = false;
            if (subscription.BalancingIncluded) FromTireset.NeedBalancing = true;

            // Commit changes to database
            db.SubmitChanges();

            // Send email to customer with information on service completion
            Customer customer = db.GetCustomer(car.CustomerId);
            SendEmail(customer.Email, customer.Name, subscriptionnumber, db.GetTireTypeDescription(ToTireset.TireTypeId), RightFrontTirePattern, LeftFrontTirePattern, RightRearTirePattern, LeftRearTirePattern); 

            // Dispose database connection
            db.Dispose();
        }

        /// <summary>
        /// Function that sends email to customer with information on completed service and with information on tire pattern
        /// </summary>
        /// <param name="CustomerEmail">Customer email that this email will be send to</param>
        /// <param name="CustomerName">Name on customer</param>
        /// <param name="SubscriptionNumber">SubscriptionNumber for customer</param>
        /// <param name="TireSetType">Tiretype description (Winther/Summer)</param>
        /// <param name="RightFront">Tirepattern on right front tire</param>
        /// <param name="LeftFront">Tirepattern on left front tire</param>
        /// <param name="RightBack">Tirepattern on right rear tire</param>
        /// <param name="LeftBack">Tirepattern on left rear tire</param>
        private void SendEmail(string CustomerEmail, string CustomerName, string SubscriptionNumber, string TireSetType, decimal RightFront, decimal LeftFront, decimal RightBack, decimal LeftBack)
        {
            string Subject = "Hjulskift gennemført - Abonnement " + SubscriptionNumber;
            bool test = Convert.ToBoolean(Convert.ToByte(ConfigurationManager.AppSettings["TestEnvironmentOn"]));
            Shared email = new Shared();

            Hashtable templateVars = new Hashtable();

            // Send email to customer
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("TireSetType", TireSetType);
            templateVars.Add("RightFront", RightFront.ToString());
            templateVars.Add("LeftFront", LeftFront.ToString());
            templateVars.Add("RightBack", RightBack.ToString());
            templateVars.Add("LeftBack", LeftBack.ToString());

            decimal legaltirepattern = Convert.ToDecimal(ConfigurationManager.AppSettings["LegalTirePattern"]);

            Shared.Parser parser = new Shared.Parser();
            if (RightFront < legaltirepattern & LeftFront < legaltirepattern & RightBack < legaltirepattern & LeftBack < legaltirepattern)
            {
                // All tires are below legal interval
                parser = new Shared.Parser(Server.MapPath("~/Reports/HtmlTemplates/CustomerEmail_ServiceCompleted_NotOk.htm"), templateVars);
            }
            else
            {
                if (RightFront < legaltirepattern | LeftFront < legaltirepattern | RightBack < legaltirepattern | LeftBack < legaltirepattern)
                {
                    // One or more tires are below legal interval
                    parser = new Shared.Parser(Server.MapPath("~/Reports/HtmlTemplates/CustomerEmail_ServiceCompleted_SingleNotOk.htm"), templateVars);
                }
                else
                {
                    // All tires are within legal interval
                    parser = new Shared.Parser(Server.MapPath("~/Reports/HtmlTemplates/CustomerEmail_ServiceCompleted_Ok.htm"), templateVars);
                }
            }
            
            MembershipUser user = Membership.GetUser();

            email.SendEmail(CustomerEmail, ConfigurationManager.AppSettings["EmailAddress"].ToString(), parser.Parse(), Subject, true, test, user.Email, null, null);
        }

        /// <summary>
        /// Button function that moves to next servicecarscheduledetail
        /// </summary>
        protected void lbtnNextCustomer_Click(object sender, EventArgs e)
        {
            try
            {
                // Move index forward
                LoadServiceCarScheduleDetail(this.MarkedServiceDetails.ElementAt((this.MarkedServiceDetails.IndexOf(this.ServiceCarScheduleDetailId) + 1)), true);

                // Update message
                lMessage.Text = "";
            }
            catch (Exception ex)
            {
                if ((ex) is ArgumentException)
                {
                    // User error - arguments not valid - show error message
                    lMessage.Text = ((ArgumentException)ex).Message;
                }
                else
                {
                    // System error - show general error message
                    lMessage.Text = "Fejl opstod - venligst prøv igen";
                }
            }
            finally
            {
                // Update message panel
                upMessage.Update();
            }
        }

        /// <summary>
        /// Button function that moves to previous servicecarscheduledetail
        /// </summary>
        protected void lbtnPreviousCustomer_Click(object sender, EventArgs e)
        {
            try
            {
                // Move index backward
                LoadServiceCarScheduleDetail(this.MarkedServiceDetails.ElementAt((this.MarkedServiceDetails.IndexOf(this.ServiceCarScheduleDetailId) - 1)), true);

                // Update message
                lMessage.Text = "";
            }
            catch (Exception ex)
            {
                if ((ex) is ArgumentException)
                {
                    // User error - arguments not valid - show error message
                    lMessage.Text = ((ArgumentException)ex).Message;
                }
                else
                {
                    // System error - show general error message
                    lMessage.Text = "Fejl opstod - venligst prøv igen";
                }
            }
            finally
            {
                // Update message panel
                upMessage.Update();
            }
        }

        /// <summary>
        /// Button function that saves customer
        /// </summary>
        protected void btnSaveCustomer_Click(object sender, EventArgs e)
        {
            try
            {
                // Save servicecarscheduledetail
                SaveTaskCompletion(this.ServiceCarScheduleDetailId);

                // Change message
                lMessage.Text = "Servicekørsel blev markeret som udført";

                // Check for multiedit
                if (this.MarkedServiceDetails != null)
                {
                    if (this.MarkedServiceDetails.Count > 1)
                    {
                        if (this.MarkedServiceDetails.IndexOf(this.ServiceCarScheduleDetailId) != (this.MarkedServiceDetails.Count - 1))
                        {
                            // Go to edit mode for next detail in multiedit list
                            LoadServiceCarScheduleDetail(this.MarkedServiceDetails.ElementAt((this.MarkedServiceDetails.IndexOf(this.ServiceCarScheduleDetailId) + 1)), true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if ((ex) is ArgumentException)
                {
                    // User error - arguments not valid - show error message
                    lMessage.Text = ((ArgumentException)ex).Message;
                }
                else
                {
                    // System error - show general error message
                    lMessage.Text = "Fejl opstod - venligst prøv igen";
                }
            }
            finally
            {
                // Update message panel
                upMessage.Update();
            }
        }

        /// <summary>
        /// Button function that saves customer and closes edit screen and return to customer overview
        /// </summary>
        protected void btnSaveCustomerClose_Click(object sender, EventArgs e)
        {
            try
            {
                // Save scheduledetail
                SaveTaskCompletion(this.ServiceCarScheduleDetailId);

                // Go to list with all tasks for completion
                RedirectToTaskCompletionList();
            }
            catch (Exception ex)
            {
                if ((ex) is ArgumentException)
                {
                    // User error - arguments not valid - show error message
                    lMessage.Text = ((ArgumentException)ex).Message;
                }
                else
                {
                    // System error - show general error message
                    lMessage.Text = "Fejl opstod - venligst prøv igen";
                }
            }
            finally
            {
                // Update message panel
                upMessage.Update();
            }
        }
    }
}